package com.foxchen.fanjingmontainticket.schedule.task;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.foxchen.fanjingmontainticket.bean.LeaveUserVO;
import com.foxchen.fanjingmontainticket.bean.TicketVO;
import com.foxchen.fanjingmontainticket.domain.TicketRecord;
import com.foxchen.fanjingmontainticket.enums.ProdInfoEnums;
import com.foxchen.fanjingmontainticket.service.TicketRecordService;
import lombok.Getter;
import okhttp3.*;
import org.dromara.hutool.core.data.PhoneUtil;
import org.dromara.hutool.core.date.DateUtil;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Map;

@SuppressWarnings("unchecked")
public class BuyTicketTask implements Runnable{
    public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
    private static final String URL = "https://etrip.icbc.com.cn/api-trip/productTicketPurchase/onlineOrderSubmit/2000001053?corpId=2000001053";
    private static final Logger log = LoggerFactory.getLogger(BuyTicketTask.class);
    private final TicketRecordService ticketRecordService;
    private final TicketVO ticketVO;
    @Getter
    private final TicketRecord ticketRecord;
    private final JavaMailSender mailSender;

    public BuyTicketTask(TicketRecordService ticketRecordService, TicketVO ticketVO, TicketRecord ticketRecord, JavaMailSender mailSender) {
        this.ticketRecordService = ticketRecordService;
        this.ticketVO = ticketVO;
        this.ticketRecord = ticketRecord;
        this.mailSender = mailSender;
    }


    @Override
    public void run() {
        try {
            int taskExecuteCount = 0;
            boolean taskStopped = false;
            while (!taskStopped) {
                taskExecuteCount += 1;

                // 超过3次 请求失败
                if(taskExecuteCount > 3){
                    throw new RuntimeException("task execute count is greater than 3，task id: " + ticketRecord.getTaskUuid());
                }

                // 第二次 第三次请求都需要睡眠一下，避免一瞬间请求太多了
                if(taskExecuteCount > 1){
                    Thread.sleep(50);
                }

                // 第一次执行 更新为执行中
                if(taskExecuteCount == 1){
                    ticketRecordService
                            .lambdaUpdate()
                            .eq(TicketRecord::getTaskUuid, ticketRecord.getTaskUuid())
                            .set(TicketRecord::getStatus,1)
                            .set(TicketRecord::getUpdateTime, DateUtil.formatDateTime(new Date()))
                            .update();
                }

                OkHttpClient client = new OkHttpClient();

                // 购票人请求信息
                String bodyJsonString = getBodyJsonString();
                RequestBody body = RequestBody.Companion.create(bodyJsonString.getBytes(StandardCharsets.UTF_8), MediaType.parse("application/json; charset=utf-8"));


                int length = bodyJsonString.getBytes(StandardCharsets.UTF_8).length;
                Request request = new Request.Builder()
                        .url(URL)
                        .post(body)
                        .addHeader("content-length", length + "")
                        .addHeader("accept", "application/json")
                        .addHeader("method", "POST")
                        .addHeader("x-trip-tag", "{\"gray\":\"V1.13.1000050.0.25040915513965\"}")
                        .addHeader("authorization", "")
                        .addHeader("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 NetType/WIFI MicroMessenger/7.0.20.1781(0x6700143B) WindowsWechat(0x63090c33) XWEB/11581 Flue")
                        .addHeader("content-type", "application/json; charset=utf-8")
                        .addHeader("origin", "https://etrip.icbc.com.cn")
                        .addHeader("sec-fetch-site", "same-origin")
                        .addHeader("sec-fetch-mode", "cors")
                        .addHeader("sec-fetch-dest", "empty")
                        .addHeader("referer", "https://etrip.icbc.com.cn/mobile/trip/tripmobile/Elife/index.html?corpId=2000001053")
                        //.addHeader("accept-encoding", "gzip, deflate, br")
                        .addHeader("accept-language", "zh-CN,zh;q=0.9")
                        .addHeader("cookie", ticketVO.getUser())
                        .build();
                try (Response response = client.newCall(request).execute()) {
                    if(response.code() == 200 && response.body() != null){
                        ResponseBody rspBody = response.body();
                        Map<String, Object> objectMap = OBJECT_MAPPER.readValue(rspBody.bytes(), new TypeReference<>() {});
                        log.info("========================response==============================");
                        log.info("{}",objectMap);
                        Map<String, Object> dataMap = (Map<String, Object>)objectMap.get("data");
                        if(Boolean.TRUE.toString().equals(dataMap.get("success").toString())){
                            taskStopped = true;
                            ticketRecordService
                                    .lambdaUpdate()
                                    .eq(TicketRecord::getTaskUuid, ticketRecord.getTaskUuid())
                                    .set(TicketRecord::getStatus,3)
                                    .set(TicketRecord::getUpdateTime, DateUtil.formatDateTime(new Date()))
                                    .update();

                            SimpleMailMessage message = new SimpleMailMessage();
                            message.setFrom("1358397900@qq.com");
                            message.setTo("1358397900@qq.com");
                            message.setSubject("抢到票了");
                            message.setText("抢到票了: %s".formatted(OBJECT_MAPPER.writeValueAsString(ticketRecord)));

                            SimpleMailMessage message1 = new SimpleMailMessage();
                            message1.setFrom("1358397900@qq.com");
                            message1.setTo("1352568281@qq.com");
                            message1.setSubject("抢到票了");
                            message1.setText("抢到票了: %s".formatted(OBJECT_MAPPER.writeValueAsString(ticketRecord)));

                            mailSender.send(message);
                            mailSender.send(message1);

                        }
                    }
                } catch (Exception e) {
                    log.error("execute error.",e);
                }
            }
        } catch (Exception e) {
            log.error("{} task execute error",ticketRecord.getTaskUuid(),e);
            ticketRecordService
                    .lambdaUpdate()
                    .eq(TicketRecord::getTaskUuid, ticketRecord.getTaskUuid())
                    .set(TicketRecord::getStatus,2)
                    .set(TicketRecord::getUpdateTime, DateUtil.formatDateTime(new Date()))
                    .update();
        }
    }

    private @NotNull String getBodyJsonString() {
        StringBuilder ticketUserInfo = new StringBuilder("[");
        for (int i = 0; i < ticketVO.getLeaveUser().size(); i++) {
            LeaveUserVO leaveUserVO = ticketVO.getLeaveUser().get(i);
            String info = """
        {
            "name": "%s",
            "idType": "0",
            "idNo": "%s",
            "contactId": "%s"
        }
        """.formatted(leaveUserVO.getName(),leaveUserVO.getIdNo(),leaveUserVO.getRecordId());
            ticketUserInfo.append(info);
            if(i < ticketVO.getLeaveUser().size() - 1){
                ticketUserInfo.append(",");
            }
        }
        ticketUserInfo.append("]");

        Double priceByProdId = ProdInfoEnums.getPriceByProdId(ticketRecord.getProdId());

        String phoneEncrypt = PhoneUtil.hideBetween(ticketVO.getUserPhone()).toString();
        // 构造请求体
        return """
        {
            "corpId": "2000001053",
            "totalAmount": "%s",
            "salesChannel": "1",
            "payWay": "4",
            "placeOrderWay": 0,
            "buyerInfo": {
                "name": "%s",
                "mobile": "%S"
            },
            "ticketInfos": [
                {
                    "prodId": "%s",
                    "travelDate": "%s",
                    "ticketNum": %s,
                    "ticketType": "1",
                    "ticketUsers": %s,
                    "timeRangeId": "%s",
                    "useTimeBeg": "%s",
                    "useTimeEnd": "%s",
                    "subTickets": []
                }
            ],
            "orderCouponNo": "",
            "customerRemark": "",
            "showSessionInfo": {}
        }
        """.formatted(
                BigDecimal.valueOf(ticketVO.getLeaveUser().size() * priceByProdId).setScale(2, RoundingMode.HALF_UP).toString(),
                ticketVO.getCallUser(),
                phoneEncrypt,
                ticketVO.getProdId(),
                ticketVO.getDateStr(),
                ticketVO.getLeaveUser().size(),
                ticketUserInfo.toString(),
                ticketVO.getTimeRangeId(),
                ticketVO.getUseTimeBeg(),
                ticketVO.getUseTimeEnd());
    }
}
